package qc.module.qms.service.log;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.enums.qms.QmsDataFlowOperateTypeEnum;
import qc.common.core.enums.qms.QmsPointDataQualityEnum;
import qc.common.core.enums.qms.QmsPointTimeSegmentEnum;
import qc.common.core.utils.IdentifierUtil;
import qc.common.core.utils.LocalDateTimeUtil;
import qc.common.core.utils.QmsTimeUtil;
import qc.module.qms.dto.mq.QmsMqPointDataMessageDto;
import qc.module.qms.dto.pointdata.QmsPointDataSaveAffectDto;
import qc.module.qms.dto.pointdata.QmsPointNumericDataDto;
import qc.module.qms.entity.QmsLogPointData;
import qc.module.qms.entity.QmsLogPointDataDetail;
import qc.module.qms.repository.QmsLogPointDataDetailRepository;
import qc.module.qms.repository.QmsLogPointDataRepository;

import java.time.LocalDateTime;
import java.util.List;

/**
 * QmsLogPointDataService
 *
 * @author QuCheng Tech
 * @since 2025/10/10
 */
@Service
public class QmsLogPointDataService {
    private static final Logger logger = LoggerFactory.getLogger(QmsLogPointDataService.class);

    @Autowired
    private QmsLogPointDataRepository repository;

    @Autowired
    private QmsLogPointDataDetailRepository detailRepository;

    /**
     * 新增点号数据日志
     *
     * @param message 点号数据消息对象
     * @param hasSend 是否已成功发送至MQ，如果已经发送至MQ不需要再重复提取后发送至MQ，如果未发送至MQ由定时任务中提取后发送至MQ
     * @return void
     * @author QuCheng Tech
     * @since 2025/10/10
     */
    public void add(QmsMqPointDataMessageDto message, boolean hasSend) {
        try {
            //传入信息错误不进行保存，保存错误或失败只进行文件日志记录，不抛出错误或异常
            //点号编码不能为空、时段类型必须正确、点号数据起止时间必须有并且正确
            if (message != null && StringUtils.isNotBlank(message.getPointid())
                    && message.getTmseg() != null && message.getTmseg() != QmsPointTimeSegmentEnum.UN_DEFINE
                    && message.getBeginTime() != null && message.getEndTime() != null
                    && message.getBeginTime().isAfter(message.getEndTime()) == false) {
                LocalDateTime now = LocalDateTimeUtil.getNow();
                QmsLogPointData en = new QmsLogPointData();
                //日志ID自动生成
                String logid = IdentifierUtil.simpleUUID();
                en.setId(logid);
                //字段赋值
                en.setPointid(message.getPointid());
                en.setPointtmtype(message.getTmseg());
                en.setPointbegintm(message.getBeginTime());
                en.setPointendtm(message.getEndTime());
                en.setIsmanual(message.isManual());
                en.setUsername(message.getUserName());
                //根据是否为人工操作和数据质量设置本次的操作类型
                if (message.isManual() == false) {
                    //如果不是人工操作，系统只有保存数据一种操作
                    en.setOptype(QmsDataFlowOperateTypeEnum.SAVE_POINT_DATA_FROM_SYS_CALC);
                } else {
                    //人工操作，判断数据质量
                    if (message.getQuality() == QmsPointDataQualityEnum.DELETE)//人工删除数据
                        en.setOptype(QmsDataFlowOperateTypeEnum.DELETE_POINT_DATA);
                    else if (message.getQuality() == QmsPointDataQualityEnum.ERROR)//人工标记为错误数据
                        en.setOptype(QmsDataFlowOperateTypeEnum.SET_POINT_DATA_IS_ERROR);
                    else if (message.getQuality() == QmsPointDataQualityEnum.MANUAL)//人工标记为正确数据
                        en.setOptype(QmsDataFlowOperateTypeEnum.SET_POINT_DATA_IS_RIGHT);
                    else//其他情况均当做是人工录入或修改数据
                        en.setOptype(QmsDataFlowOperateTypeEnum.SAVE_POINT_DATA_FROM_MANUAL_ENTRY);
                }

                en.setAffectcount(message.getAffectCount());
                en.setFailcount(message.getFailCount());
                en.setHassend(hasSend);
                //如果已发送至MQ标记为true，设置发送时间为当前时间
                if (hasSend == true)
                    en.setSendtm(now);
                //设置写入时间当前时间
                en.setIntm(now);

                if (repository.insert(en) > 0x0) {
                    //日志保存成功后，判断是否要保存点号数据变化明细记录；不判断消息中的操作类型和数据质量，只判断受影响的数据集合不为空时均进行明细记录
                    List<QmsPointDataSaveAffectDto> affectDatas = message.getAffectDatas();
                    if (affectDatas != null && affectDatas.size() > 0x0) {
                        for (QmsPointDataSaveAffectDto affectData : affectDatas) {
                            try {
                                QmsPointNumericDataDto data2 = affectData.getData();
                                logger.debug("add affectData.getData().getTm()=" + QmsTimeUtil.format(affectData.getData().getTm(), message.getTmseg()));
                                //判断本次新增或修改的数据不为空
                                if (data2 != null && data2.getTm() != null) {
                                    QmsLogPointDataDetail detail = new QmsLogPointDataDetail();
                                    //日志明细ID自动生成
                                    detail.setId(IdentifierUtil.simpleUUID());
                                    //日志ID使用已生成的ID
                                    detail.setLogid(logid);
                                    //数据时标
                                    detail.setTm(data2.getTm());
                                    //设置ops
                                    detail.setOps(affectData.getOps());
                                    //先设置本次新增或修改的数据信息
                                    detail.setV2(data2.getV());
                                    detail.setBeginv2(data2.getBeginv());
                                    detail.setEndv2(data2.getEndv());
                                    detail.setMaxv2(data2.getMaxv());
                                    detail.setMaxtm2(data2.getMaxtm());
                                    detail.setMinv2(data2.getMinv());
                                    detail.setMintm2(data2.getMintm());
                                    detail.setUptm2(data2.getUptm());
                                    detail.setQuality2(data2.getQuality());

                                    //判断操作类型集合，为0表示新增数据不需要设置已有数据信息
                                    if (affectData.getOps() > 0x0 && affectData.getExistData() != null) {
                                        QmsPointNumericDataDto data1 = affectData.getExistData();
                                        detail.setV1(data1.getV());
                                        detail.setBeginv1(data1.getBeginv());
                                        detail.setEndv1(data1.getEndv());
                                        detail.setMaxv1(data1.getMaxv());
                                        detail.setMaxtm1(data1.getMaxtm());
                                        detail.setMinv1(data1.getMinv());
                                        detail.setMintm1(data1.getMintm());
                                        detail.setUptm1(data1.getUptm());
                                        detail.setQuality1(data1.getQuality());
                                    }

                                    detailRepository.insert(detail);
                                }
                            } catch (Exception ex) {
                                logger.error("保存点号数据日志明细信息时异常，" + ex.getMessage());
                            }
                        }
                    }
                }
            }
        } catch (Exception ex) {
            logger.error("保存点号数据日志信息时异常，" + ex.getMessage());
        }
    }

    /**
     * 设置点号数据日志已成功发送至MQ
     *
     * @param logid 日志ID
     * @return void
     * @author QuCheng Tech
     * @since 2025/10/10
     */
    public void setHasSend(String logid) {

    }
}
